//
//  CDLocationService.swift
//  CandyDate
//
//  Created by zolobdz on 2017/10/23.
//  Copyright © 2017年 HeChao. All rights reserved.
//

import Foundation
import AMapLocationKit
import CoreLocation
import AMapSearchKit
import MapKit
class CDLocationService : NSObject{
    
    static let shared = CDLocationService()
    private override init() {}
    
    lazy var amaplocationManager = AMapLocationManager()
    lazy var amapSearchManager = AMapSearchAPI()
    weak open var reGeocodeDelegate: CDMapSearchReGeocodeDelegate?
    
    lazy var locationManager = CLLocationManager()
    var timer: DispatchSourceTimer?
    // info
    lazy var gpsCity = ""
    var locationCoordinate2D: CLLocationCoordinate2D? // nil为没有定位到经纬度
    lazy var shangHaiCoordinate2D = CLLocationCoordinate2D(latitude: CLLocationDegrees(31.22), longitude: CLLocationDegrees(121.48))
    func startService() {
        AMapServices.shared().enableHTTPS = true
        AMapServices.shared().apiKey = "2cefb2fe1038ba017f317d4ee780cf65"
        amaplocationManager.delegate = self
        amaplocationManager.distanceFilter = 1000
        amaplocationManager.locatingWithReGeocode = true
        amapSearchManager?.delegate = self
        locationManager.delegate = self
        statrtUpdateLocation()
        startUploadUserPositionLoop()
    }
    
    // 权限
    
    func requestLocationServiceWhenInUse() {
        locationManager.requestWhenInUseAuthorization()
    }
    
    func checkIsDeviceLocationEnable() -> Bool {
        return CLLocationManager.locationServicesEnabled()
    }
    
    func checkIsOpenAppLocationAuthority() -> Bool {
        switch CLLocationManager.authorizationStatus() {
        case .denied,.restricted,.notDetermined:
            return false
        case .authorizedAlways,.authorizedWhenInUse:
            return true
        }
    }
    
    func showAuthorizationStatus() {
        switch CLLocationManager.authorizationStatus() {
        case .notDetermined:
            CDLocationService.shared.requestLocationServiceWhenInUse()
//            DispatchQueue.main.asyncAfter(deadline: .now() + 0.7, execute: {
//                CDLocationService.shared.requestLocationServiceWhenInUse()
//            })
        case .denied,.restricted:
            if !CDLocationService.shared.checkIsDeviceLocationEnable() || !CDLocationService.shared.checkIsOpenAppLocationAuthority()
            {
                let alert = UIAlertController(title: nil, message: "为了准确找到附近合适你的用户，您需要在手机系统的[设置】->【隐私】->【定位服务】中打开定位服务并允许糖圈使用定位服务。", preferredStyle: .alert)
                let okAction = UIAlertAction(title: "去设置", style: .default, handler: { (action) in
                    let url = URL(string: UIApplicationOpenSettingsURLString)
                    if url != nil && UIApplication.shared.canOpenURL(url!)
                    {
                        UIApplication.shared.open(url!, options: [:], completionHandler: nil)
                    }
                })
                let cancel = UIAlertAction(title: "取消", style: .cancel, handler: nil)
                alert.addAction(cancel)
                alert.addAction(okAction)
                if let viewController = UIManager.shared.mainWindow.rootViewController!.presentedViewController
                {
                    viewController.present(alert, animated: true, completion: nil)
                }
                else
                {
                    UIManager.shared.mainWindow.rootViewController!.present(alert, animated: true, completion: nil)
                }
            }
        default:
            break
        }
    }
    
    //上报位置信息
    
    private func startUploadUserPositionLoop() {
        timer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.global())
        timer!.schedule(deadline: .now()+0.5, repeating: 60*10)
        timer!.setEventHandler {
            self.userUploadLocation()
        }
        timer!.resume()
    }
    
    func userUploadLocation() {
        
        guard let userID = MyselfSingleton.shared.userInfo?.userID,!userID.isEmpty else {
            return
        }
        
        guard locationCoordinate2D != nil else {
            return
        }
        
//        let api = CDRequestAPI.uploadUserLocation(ShowHudKey: false, userID: userID, longitude: locationCoordinate2D!.longitude.stringValue(), latitude: locationCoordinate2D!.latitude.stringValue(), city: gpsCity)
//        CDNetWorkService.requestDataWithTarget(target: api, successClosure: {  (obj, code, message) in
//            _ = code == 10 ? CDUtility.log("位置信息上传成功") : CDUtility.log("位置信息上传失败")
//        }) { (msg) in
//            CDUtility.log(msg)
//        }
    }
    
    func statrtUpdateLocation() {
        amaplocationManager.startUpdatingLocation()
    }
    
    //MARK: Search Task
    
    func startAMapReGeocodeSearchRequest(_ request: AMapReGeocodeSearchRequest) {
        amapSearchManager?.aMapReGoecodeSearch(request)
    }
}

extension CDLocationService : AMapLocationManagerDelegate,CLLocationManagerDelegate{
    
    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        switch status {
        case .denied,.notDetermined,.restricted:
//            showAuthorizationStatus()
            break
        default:
            statrtUpdateLocation()
        }
    }
    
    func amapLocationManager(_ manager: AMapLocationManager!, didFailWithError error: Error!) {
        locationCoordinate2D = nil
        gpsCity = ""
        // failed
    }
    
    func amapLocationManager(_ manager: AMapLocationManager!, didUpdate location: CLLocation!, reGeocode: AMapLocationReGeocode!) {
        // success
        var distance = 1000
        if locationCoordinate2D != nil {
            let my = MKMapPointForCoordinate(locationCoordinate2D!)
            let now = MKMapPointForCoordinate(location.coordinate)
            distance = Int(MKMetersBetweenMapPoints(my, now)) // 单位米
        }
        locationCoordinate2D = location.coordinate
        
        guard let reGeoCodeInfo = reGeocode else {
            gpsCity = ""
            if distance > 100 // 保证上报位置
            {
                userUploadLocation()
            }
            return
        }
        var tempGPS = reGeoCodeInfo.city
        if tempGPS == nil || tempGPS!.isEmpty
        {
            tempGPS = reGeoCodeInfo.province // 上海北京重庆直辖市
        }
        guard tempGPS != nil else { // 拿不到城市
            gpsCity = ""
            if distance > 100 // 保证上报位置
            {
                userUploadLocation()
            }
            return
        }
        gpsCity = tempGPS!.replacingOccurrences(of: "市", with: "")
        
        if distance > 100 // 保证上报位置
        {
            userUploadLocation()
        }
        
//        if distance > 100
//        {
//            let reGeoCodeSearchRequest = AMapReGeocodeSearchRequest()
//            reGeoCodeSearchRequest.location = AMapGeoPoint.location(withLatitude: locationCoordinate2D!.latitude.cgFloatValue(), longitude: locationCoordinate2D!.longitude.cgFloatValue())
//            reGeoCodeSearchRequest.requireExtension = false
//            amapSearchManager!.aMapReGoecodeSearch(reGeoCodeSearchRequest)
//        }
    }
    
}

extension CDLocationService : AMapSearchDelegate{
 
    func aMapSearchRequest(_ request: Any!, didFailWithError error: Error!) {
        
        if let poiRequest = request as? AMapPOISearchBaseRequest
        {
            if poiRequest.requireExtension
            {
                // 地点搜索失败 回调
            }
            return
        }
        
        if let poiRequest = request as? AMapReGeocodeSearchRequest
        {
            gpsCity = ""
            if poiRequest.requireExtension
            {
                // 地点搜索失败 回调
                if reGeocodeDelegate != nil && reGeocodeDelegate!.responds(to: #selector(onReGeocodeSearchDone(_:response:))){
                    reGeocodeDelegate!.onReGeocodeFinished?(nil, error: error)
                }
            }
            return
        }
    }
    
    func onReGeocodeSearchDone(_ request: AMapReGeocodeSearchRequest!, response: AMapReGeocodeSearchResponse!) {
        /*
         requireExtension
         false: CDLocationService 自己调用地理位置反编码
         true: 其他控制器调用地理位置反编码，需要设置代理或回调
         */
        if request.requireExtension
        {
            // 地点搜索回调
            if reGeocodeDelegate != nil{
                reGeocodeDelegate!.onReGeocodeFinished?(response, error: nil)
            }
        }
        else
        {
            var tempGPS = response.regeocode.addressComponent.city
            if tempGPS == nil || tempGPS!.isEmpty
            {
                tempGPS = response.regeocode.addressComponent.province // 上海北京重庆直辖市
            }
            gpsCity = tempGPS!.replacingOccurrences(of: "市", with: "")
            // 记录和选择城市
        }
    }
}




@objc protocol CDMapSearchReGeocodeDelegate : NSObjectProtocol {
    @objc optional func onReGeocodeFinished(_ response: AMapReGeocodeSearchResponse?, error: Error?)
}

